home *** CD-ROM | disk | FTP | other *** search
/ Amiga Packmags / Source, The - Issue 5 (1993)(Epsilon)[WB].zip / Source, The - Issue 5 (1993)(Epsilon)[WB].adf / Source / Music / GMod.lha / GMOD.doc < prev    next >
Text File  |  1992-05-25  |  30KB  |  587 lines

  1.                                    GMOD
  2.                        Self-Contained Module Format
  3.                           Description of Standard
  4.                          Copyright 1992 Bryan Ford
  5.                                Version 1.01
  6.  
  7.  
  8.  
  9.                                Introduction
  10.                                ~~~~~~~~~~~~
  11.  
  12.     The GMOD format is a format which can interface any music module with
  13. embedded player code with any program that wants to play the music.  (It is
  14. NOT a specification for a general music file format.)  It has many powerful
  15. features, but is designed to be as simple as you want it to be. The 'least
  16. common denominator' support is very small, so the module can be small and
  17. quick.  In many cases, all that is needed to write a GMOD module is to tack
  18. on a short constant header before a normal module.
  19.  
  20.     GMODs can also be very useful to game/demo programmers that want to
  21. include music in their programs.  If modules are saved as GMODs, then the
  22. programmer can simply code for the GMOD format, and the person writing the
  23. music can use whatever music composer program is convenient.  The
  24. programmer simply makes a few calls to the GMOD module, and it plays
  25. itself, without the programmer having to worry about finding the correct
  26. replayer code and such.
  27.  
  28.     GMOD modules come in two main types: Amiga-specific and "portable".
  29. Amiga-specific modules are modules that bang on the Amiga custom chip
  30. hardware directly, as described later, to play music.  These modules can be
  31. portable across Amiga music players, games, demos, etc.  Portable modules
  32. do not access any hardware directly; instead, they use the NotePlayer
  33. standard to play notes, and use the facilities provided by the GMOD format
  34. for timing.  Portable modules can potentially be played on ANY 680x0-based
  35. system: Amiga, Atari ST, Mac, NeXT, etc.  The type of module is defined by
  36. what is at the module+$20 entrypoint, described later.
  37.  
  38.     If GMOD catches on, we may start to see music maker programs that write
  39. full-featured GMOD modules that are not only playable with most any simple
  40. player program, but also support many specialized features such as external
  41. control (volume, speed, fast-forward, rewind, etc.), real-time sound
  42. effects added to the music (for games or other sound effects), and whatever
  43. else you can imagine.
  44.  
  45.     This document is intended especially for distribution with my music
  46. player MultiPlayer (which of course supports this format).  Wherever
  47. MultiPlayer goes, this document goes.  However, since the GMOD format isn't
  48. really tied to MultiPlayer, MultiPlayer doesn't have to go wherever this
  49. document goes.  You may also distribute this document apart from
  50. MultiPlayer, put it on public bulletin board systems, or even include it
  51. along with commercial programs if you are so inclined, as long as it
  52. remains unchanged.  (If you have suggestions or ideas, I'll be glad to try
  53. and incorporate them - I just don't want multiple standards documents
  54. floating around.)
  55.  
  56.     At the end of this document are described two other module formats,
  57. XMOD and AMOD, which are very simple module formats that I used before the
  58. GMOD format was developed.  GMOD replaces both previous formats, so please
  59. don't write programs that create XMOD or AMOD modules.  Although
  60. MultiPlayer can still play them (and probably always will be able to), and
  61. you may still create them if you want something extremely simple and quick,
  62. for general purpose use you should always use GMODs.
  63.  
  64.     In this document, when I refer to the 'player', I am referring to the
  65. program that uses the module (the caller), such as MultiPlayer, not the
  66. actual player code in the module itself.  As such, 'player' used in this
  67. context can also mean a game or demo that uses a GMOD module.  I refer to
  68. the module, both the music-playing code and any private song data, as just
  69. the 'module'.
  70.  
  71.  
  72.  
  73.                            Format Specification
  74.                            ~~~~~~~~~~~~~~~~~~~~
  75.  
  76.     Now for the actual definition.  A GMOD file always begins with four
  77. specific longwords, then a jump table with an arbitrary length, then the
  78. rest of the file can be anything you want.  The format follows:
  79.  
  80. module+$00      'GMOD' ($474D4F44)
  81. module+$04      4-byte ID of program that created this module
  82. module+$08      Memory address where this module MUST be loaded, 0 if relocatable
  83. module+$0c      Offset of end of jump table (=numentries*4+$10)
  84. module+$10      Start of jump table (arbitrary length)
  85.  
  86.     The first longword in the file is simply used to identify GMOD modules.
  87.  
  88.     The ID of the creator (module+$04) is used to identify the program that
  89. created this module.  It can be ignored by any program that simply wants to
  90. play the module.  A music composer program might check this longword when
  91. trying to re-load a module to make sure the module is the correct type.
  92. When selecting an ID for your program to use, think of it as an IFF chunk
  93. ID:  Try to select something that is somewhat readable ASCII, but is
  94. unlikely to collide with some other program.  (For example, don't use
  95. 'SONG' or 'TRAK' or something simple like that.)
  96.  
  97.     The load address is the absolute location in memory where the module
  98. must be loaded.  Although hopefully programmers will have enough sense not
  99. to create non-relocatable modules in the future, the feature is there for
  100. current module types that use absolute addresses in the code and/or data.
  101. In the MultiPlayer implementation using this feature is not dangerous to
  102. the system and will never cause innocent memory to be stomped on, but it
  103. may cause the module to be unable to load even when there's plenty of
  104. memory.  If the required memory area is already occupied (even if it's just
  105. a few bytes somewhere in the required range), MultiPlayer will refuse to
  106. load the module.  Therefore, this feature should never be used except when
  107. absolutely necessary, since these modules may not be able to load even when
  108. there is plenty memory available.  MultiPlayer properly allocates the
  109. needed memory with AllocAbs, rather than just overwriting memory as many
  110. European demos do, so multitasking will never cause the module to get
  111. overwritten.  I wish this feature wasn't necessary, but sometimes we just
  112. have to clean up other people's messes, don't we?
  113.  
  114.     The offset of the end of the jump table is the offset (from the start
  115. of the module) pointing to just past the last valid jump table entry.  It
  116. can be calculated using the equation (numvecs*4)+16, where numvecs is the
  117. number of vectors in the jump table.  Any vectors beyond this offset are
  118. assumed by the player (caller) to be 'do-nothing' routines - i.e.  just an
  119. RTS.
  120.  
  121.     The actual jump table entries are usually branches or PC-relative jump
  122. instructions, but can be any code that fits in four bytes.  In particular,
  123. if a function simply wants to return a constant value (such as
  124. GetNumSongs), a MOVEQ and an RTS could fit right into the jump table.  The
  125. player must not try to interpret the jump table entries (and by no means
  126. modify it!).  The one exception to this rule is that the player may look
  127. into the jump table to see if the first word of the entrypoint is $4E75
  128. (RTS), in which case the player knows that the entry is not used.  This
  129. way, the player can avoid bogging down the system with unused interrupts
  130. and such.
  131.  
  132.     The calling conventions are always standard Amiga conventions:  The
  133. routines must save registers D2-D7 and A2-A6, and must return with an RTS.
  134. Parameters are passed in various registers and returned in D0, the same way
  135. as standard Amiga libraries.
  136.  
  137.     Note that, since any of the entries may be omitted, special care must
  138. be taken by the caller when calling the module.  First, before calling a
  139. particular entrypoint, the offset must be tested against the MaxVecOfs in
  140. the module.  If the offset is greater than OR EQUAL to MaxVecOfs, the
  141. routine does not exist, and behaves the same way as if the entrypoint was a
  142. do-nothing entrypoint (first word is RTS).  Second, when the caller is
  143. expecting a return code of some kind in D0, before calling the module it
  144. must initialize D0 to some default value, or an invalid value it can
  145. recognize, in case the routine is a do-nothing or nonexistent entrypoint.
  146. For example, before calling the GetNumSongs function, D0 should be
  147. initialized to 1.  If GetNumSongs doesn't exist or does nothing, the
  148. default value of one song will be assumed.
  149.  
  150.     I will not specify whether or not operating system routines (such as
  151. Exec's memory allocation routines) may be called from within the module.
  152. For a general-purpose player program like MultiPlayer, this should be
  153. allowed.  However, I expect that the majority of music modules for a long
  154. time to come will stay away from the operating system in order to support
  155. games and demos and other programs that take over the machine.  If the
  156. operating system is to be used normally, it is always the caller's
  157. (player's) responsibility to allocate the audio.device's channels and make
  158. sure the module fits into the multitasking system.  All the module needs to
  159. do is stick to the standard audio hardware registers (and audio DMA
  160. control) and keep its nose out of forbidden areas.  Modules should generally
  161. not need to muck around in interrupts, since the format defines some very
  162. general-purpose interrupt routines, but I won't forbid it either.  If a module
  163. wants to do its own interrupt processing, then all the module's interrupt
  164. entrypoints (VBlank50, VBlank60, and TimerTick) should be do-nothing, and
  165. the module should properly allocate the interrupts using system calls.
  166.  
  167.     The currently defined jump table entries are described below:
  168.  
  169.  
  170. module+$10      InitMusic
  171.  
  172.     Called to initialize the module.  This is generally the first routine
  173. called by a player program after loading the module.  It should be called
  174. only once, and the module may be started and stopped as many times as
  175. needed after a single call to InitMusic.  D0 must be set to NULL before
  176. calling the routine, and the initialization routine should return NULL in
  177. D0 if the initialization succeeded, or a pointer to a string (in D0)
  178. describing the error if the initialization failed.  No other routines in
  179. the module may be called before initialization.  InitMusic should not mess
  180. with the audio hardware or start playing music, as the audio channels may
  181. not be allocated by this time.  This entrypoint would generally be used to
  182. perform any relocation or other one-time initialization of the module, or
  183. for allocating memory or other resources through the operating system if
  184. necessary.
  185.  
  186.  
  187. module+$14      StartMusic
  188.  
  189.     Called to start playing the music.  If the module contains several
  190. songs, then D0 will hold the song number (0..n-1) to start playing,
  191. otherwise D0 will be 0.  StartMusic always starts a given song at the
  192. beginning.  To pause and restart in the middle of a song, use PauseMusic
  193. and RestartMusic.
  194.  
  195.     Any given module is always guaranteed to have a song number 0.  Before
  196. calling StartMusic with a song number greater than zero, it must call
  197. GetNumSongs to make sure that song actually exists.  There is not
  198. necessarily any protection in the module against playing songs that do not
  199. exist.
  200.  
  201.     The StartMusic entrypoint may be called again after StopMusic to
  202. restart the music after it was stopped.  This allows the module to be
  203. 're-used' without reloading.  Also, it allows switching songs in the module
  204. if the module contains more than one song.  However, StartMusic should
  205. never be called after another StartMusic, without a StopMusic in between.
  206.  
  207.  
  208. module+$18      StopMusic
  209.  
  210.     Called to stop playing the music.  Often all this does is turn off
  211. audio DMA and return.  StopMusic may be called any number of times, with or
  212. without a corresponding StartMusic call.
  213.  
  214.     Note that no interrupt entrypoints in the module are called by the
  215. player anytime except when the music is actually playing, i.e.  after
  216. StartMusic and before StopMusic.  Therefore, the player program should
  217. enable audio interrupts AFTER StartMusic, and disable interrupts BEFORE
  218. StopMusic.
  219.  
  220.  
  221. module+$1c      EndMusic
  222.  
  223.     Called to shut down the module and prepare to be unloaded.  The caller
  224. MUST call this entry before unloading the module, even if the call to
  225. InitMusic failed.  If the music was playing, StopMusic must be called
  226. before calling EndMusic.  This may be called more than once successively,
  227. but no other routines in the module may be called after EndMusic has been
  228. called.  A module may not be re-used after EndMusic.  EndMusic should not
  229. mess with audio hardware or DMA registers - that is done in StopMusic.
  230. This entrypoint is provided mainly to free any allocated memory or do other
  231. operating-system related cleanup.  As such, for most current modules this
  232. entrypoint would do nothing.
  233.  
  234.  
  235. module+$20      NotePlayer
  236.  
  237.     If this entrypoint is implemented, then this module can be portable: it
  238. does not have to access the Amiga audio hardware directly. If the client
  239. supports portable modules, BEFORE it calls InitMusic, it must call this
  240. entrypoint with a pointer to a NotePlayer jump table in A0 and 0 in D0.
  241. (NotePlayers are described in the separate "NotePlayer.doc".)  If the
  242. module supports portable mode, it must save the NotePlayer pointer and
  243. return nonzero in D0.  Later, the module will use the provided NotePlayer
  244. routines to play its music instead of going to the hardware directly.
  245.  
  246.     A GMOD may be made capable of playing either with or without an
  247. externally specified NotePlayer.  In this case, it generally keeps an
  248. internal "backup" NotePlayer (such as the "notehard.asm" supplied with the
  249. NotePlayer standard) which it defaults to if it is not given a NotePlayer
  250. by the client.
  251.  
  252.     It is the responsibility of the module to initialize and shut down the
  253. NotePlayer.  The module must call the NotePlayer's NoteInit entrypoint
  254. during its InitMusic call, and it must call the NotePlayer's NoteFinish
  255. entrypoint from its EndMusic routine.
  256.  
  257.  
  258. module+$24      ContinueMusic
  259.  
  260.     After the player has called StopMusic (but before it calls EndMusic),
  261. it can call ContinueMusic to try and continue the music at the position
  262. where it was stopped.  The player calls this function with D0=0, and if
  263. the module is able to restart the music, it should return D0=1; otherwise
  264. it should leave D0 at 0.  The player must ONLY start sending interrupts
  265. again if the module returned nonzero in D0 - otherwise, the module
  266. doesn't support this feature and turning interrupts on at this point
  267. might cause trouble.  The player can always call StartMusic again to
  268. restart the module at the beginning.
  269.  
  270.  
  271. module+$28      VBlank50
  272. module+$2c      VBlank60
  273.  
  274.     The player program must call whichever of these vectors are supplied,
  275. at the appropriate frequency.  The VBlank50 routine will be called 50 times
  276. per second, the VBlank60 routine will be called 60 times per second.  The
  277. module may use either one of these routines (not both).  If the player
  278. calls these routines from a vertical blank interrupt (as is usually the
  279. case, but not necessarily), it is its responsibility to adjust the
  280. frequency appropriately.  Note that a more general timing system is also
  281. available, described below.
  282.  
  283.  
  284. module+$30      Channel0
  285. module+$34      Channel1
  286. module+$38      Channel2
  287. module+$3c      Channel3
  288.  
  289.     These four entrypoints, if supplied, are called by the player whenever
  290. the corresponding audio channels are reloaded.  They correspond to Exec's
  291. AUD0-AUD3 interrupts (levels 7-10), CPU level 4.
  292.  
  293.  
  294. module+$40      GetNumSongs
  295.  
  296.     Some music modules have more than one song in the same module.  This is
  297. useful when you want several separate musical scores that all use the same
  298. set of instruments, for memory efficiency.  If this entrypoint is supplied,
  299. the player program may call this routine to find out how many different
  300. songs are contained in this module.  The routine must be called with D0 = 1
  301. (the default number of songs), and the module should return the actual
  302. number of songs in D0.  Once the player knows how many songs are in the
  303. module, it may select the song to play in the call to StartMusic.
  304.  
  305.  
  306. module+$44      GetSongName
  307.  
  308.     If a module contains several songs, GetSongName provides a method for
  309. the player to find the name of each song.  This may be simply displayed to
  310. the user while the song is playing, or a list of songs may be built for the
  311. user to select from by name.  This routine is called with D0 holding NULL
  312. and D1 holding the song number (which must be in the proper range).  If the
  313. module supplies this routine, it must return a pointer to the song name in
  314. D0.  Otherwise, D0 will remain NULL and the song will remain nameless.
  315.  
  316.  
  317. module+$48      GetSongAuthor
  318.  
  319.     This routine works the same way as GetSongName, except the name of the
  320. song's author is returned.  If all the songs in the module are by the same
  321. person (or if the module contains only one song), D1 can be ignored.
  322.  
  323.  
  324. module+$4c      GetFrequency
  325. module+$50      TimerTick
  326.  
  327.     These routines can be used by modules for more general-purpose timing,
  328. or for odd timing values not based on the vertical blank interrupt.  If the
  329. module uses this method of timing, both of these functions must be
  330. implemented, and neither VBlank50 or VBlank60 may be.  The GetFrequency
  331. function must simply return the number of ticks per second the module
  332. requires in d0.  The TimerTick function will then be called (probably from
  333. an interrupt) at the specified frequency while the module is playing, just
  334. like the VBlank functions.
  335.  
  336.  
  337. module+$54      GetMakerName
  338.  
  339.     This entrypoint must be called with D0=0, and if it is implemented,
  340. must return the name of the program that was used to create this module.
  341. Although music maker programs should use the ID field at offset 4 to
  342. recognize specific module types, this string can be used by player programs
  343. and such to identify the module's origin for the user.
  344.  
  345.  
  346. module+$58      Hook
  347.  
  348.     This function is called by the player with D0=0, D1=hook flags, and A0
  349. pointing to a standard Hook structure as defined in the 2.0 header files.
  350. (This does not mean that modules or players that use this feature must run
  351. on 2.0 - this structure is just used for convenience.) The hook flags work
  352. very much like Intuition's IDCMP flags and tell the module what kinds of
  353. events the player wants to hear about.  If the module supports this call,
  354. it must save the pointer to the Hook (it will remain valid until after
  355. EndMusic is called) and return in D0 the hook flags indicate what hooks the
  356. module supports.
  357.  
  358.     During playing, the module will call the player's Hook for the events
  359. that the player specified (in D1 in the Hook call) AND the module supports
  360. (returned in D0 from the Hook call).  Standard Hook calling conventions
  361. must be used:  A0 points to the Hook structure that the player originally
  362. passed to the module, and A1 points to an appropriate 'message' or parameter
  363. packet (see below).  The 'object' passed in A2 is currently unused, but may
  364. be used in future message types.
  365.  
  366.     The message that the module passes to the player's Hook function depends
  367. on the type of event.  The first longword of the message always contains
  368. a single Hook Flags bit set, indicating the type of event (just like IDCMP
  369. messages).  Note that the message is NOT a standard Exec message.  After
  370. the first longword, more data can be passed depending on the event.
  371.  
  372.     The player may call the module's Hook entrypoint more than once.
  373. However, the Hook pointer passed to the module must ALWAYS be the same!
  374. Therefore, re-calling this entrypoint can only be used to change the
  375. 'active' event bits (ala ModifyIDCMP()), not to change the Hook pointer
  376. itself.
  377.  
  378.     Note that the module's entrypoints are not necessarily reentrant, so
  379. the player's Hook function must NEVER call any of the module's entrypoints,
  380. or make any calls that might indirectly cause one of the entrypoints to be
  381. called.
  382.  
  383.     Currently the following event types are defined:
  384.  
  385.  
  386. BITDEF  GMODH,REPEAT,0
  387.  
  388.     If supported and requested, the module calls the Hook function as
  389. soon as the music is about to wrap around and repeat itself.  If the
  390. player's intent is to stop the module when it repeats, it must set a flag
  391. or signal a parent Task - it must not directly call the module's StopMusic
  392. entrypoints (see above).  The message passed to the player's Hook must, of
  393. course, have the first longword set to GMODHF_REPEAT (1<<0), but other than
  394. that the message is unused.
  395.  
  396.  
  397. BITDEF  GMODH,SEQUENCE,1
  398.  
  399.     If supported and requested, the module calls the player's Hook whenever
  400. the music's sequence number changes.  This event type is specifically
  401. designed for music formats with Soundtracker-like sequences:  if the music
  402. format doesn't use such sequences, then this event type should be left
  403. unimplemented by the module.  The sequence number starts at 0 and goes to a
  404. maximum of length-1 (length is the number of sequences in the module).  The
  405. message passed to the player's Hook must have GMODHF_SEQUENCE (1<<1) in the
  406. first longword, the new sequence number in the second longword (offset 4),
  407. and the total number of sequences in the third longword (offset 8).  The
  408. module should also call this Hook once during the PlayMusic call, or very
  409. soon afterwards, so the player knows immediately how long the module is.
  410.  
  411.  
  412. module+$5c      Jump
  413.  
  414.     Instructs the module to jump to a particular position within the
  415. current song.  This is extremely module-dependent.  The player passes D0=0
  416. and the position to jump to (a longword) in D1.  For Soundtracker-like
  417. modules, this position is probably the sequence number.  For other modules,
  418. it may be a time value or whatever.  If the module successfully jumps to
  419. the requested position (it should do range checking and such first), it
  420. returns D0=1, otherwise it leaves or sets D0=0.  This entrypoint exists to
  421. allow users and programmers to do nifty tricks with specific modules - the
  422. player can't and shouldn't interpret or use this entrypoint by itself.
  423.  
  424.  
  425. module+$60      SetVolume
  426.  
  427.     Gives the module a new master volume.  If the module supports this
  428. feature, the master volume set by this entrypoint must be independent of
  429. all internal volume effects and such.  In other words, all internal volume
  430. controls must be relative to this volume.  The new master volume should be
  431. made effective immediately - not on the next note or internal volume change.
  432.  
  433.     This entrypoint is passed two volume parameters: the left-side volume
  434. in D0, and the right-side volume in D1.  Each parameter ranges from $0
  435. (minimum) to $100 (maximum).  To get a custom-chip-style volume (0-64),
  436. just shift this value right two bits.  To scale an internal volume, just
  437. multiply the two volumes and shift right 8 bits.
  438.  
  439.  
  440. module+$64      GetScroll
  441.  
  442.     This entrypoint exists for the single purpose of allowing music
  443. composers to include all their useless ramblings in their modules for
  444. everyone else to wade through.  It must be called with D0=0, and if it
  445. exists, it will return in D0 a pointer to one (probably LONG)
  446. null-terminated string, which is the entire scroll text.  The only control
  447. codes it may contain are newlines (ASCII 10).  This makes it easy to create
  448. a scroll text simply from a text file.  The player displaying the scroll
  449. text will probably just ignore these control codes. (Of course, the player
  450. wouldn't have to implement a "traditional" scroller - it can display the
  451. text however it wants.)
  452.  
  453.  
  454.     I have many other possible entrypoints and hooks in mind, but haven't
  455. gotten them standardized yet (much less implemented in MultiPlayer), so
  456. I'll leave them out for now.  If there's something you want, drop me a line
  457. and I'll go ahead and add it to the specification, whether or not
  458. MultiPlayer can support it.  (It probably can.)  The important thing is to
  459. keep the interface powerful, easy to use, and standardized.
  460.  
  461.     To use GMOD modules in your own programs, such as games or demos, all
  462. you have to do is call the appropriate entrypoints at the appropriate
  463. times.  If your program will only be using one module, or a limited number
  464. of modules all made with the same program, you can make assumptions about
  465. the module, i.e., which interrupt timing routine to call, etc.  A minimum
  466. implementation might be as simple as two calls:  one to the initialization
  467. code, and one during each VBlank interrupt.  (Many modules do nothing more
  468. than turn audio DMA off in their exit code.) Of course, if you want to be
  469. compatible with more modules, you'll have to put in a little more effort.
  470.  
  471.     If you are the author of a music-composer program, I hope you will
  472. seriously consider supporting GMOD modules.  As I said at the top of this
  473. document, I'll do everything I can to make life easy for you.  A minimal
  474. implementation can be done very quickly and with very little overhead.
  475. Modules with built-in players are becoming more and more popular, and I
  476. believe a standard, extensible caller interface could benefit both
  477. musicians and programmers.
  478.  
  479.  
  480.  
  481.                         The XMOD format (obsolete)
  482.                         ~~~~~~~~~~~~~~~~~~~~~~~~~~
  483.  
  484.     Besides the standard module formats that MultiPlayer understands, there
  485. is also a new format you can use to turn just about anything into a
  486. multitasking module.  Basically, you go into the program you want to rip
  487. the music out of with some kind of debugger (I use S.I.M.), find the player
  488. and module (with luck, they'll be right next to each other; otherwise you
  489. have to shuffle things around a little), and add an XMOD header at the
  490. beginning so that MultiPlayer (or another player that supports XMOD format)
  491. knows what to do with it.
  492.     The XMOD format is very simple:
  493.  
  494. module+$00      'XMOD'
  495. module+$04      InitEntry
  496. module+$08      PlayEntry
  497. module+$0c      StopEntry
  498.  
  499.     When MultiPlayer loads a module and finds an 'XMOD' in the beginning of
  500. it, it first calls module+$04 to let the player initialize itself and the
  501. module, then it calls module+$08 50 times per second (the normal vertical
  502. blanking interrupt speed on PAL systems), and finally calls module+$0c when
  503. the user stops the module.  The player must be PC-relative, or it must do
  504. its own relocation in the initialization code.  The entire file is always
  505. loaded into chip memory in one continuous block.
  506.     All three entrypoints must use standard Amiga calling conventions and
  507. save registers D2-D7/A2-A6.  This includes the PlayEntry - it may not
  508. modify A5/A6 even though it's normally called from an interrupt routine.
  509. They may use D0-D1/A0-A1 without restoring them.  No parameters are passed
  510. to any of the entries, and no return codes are checked for.  All three
  511. routines must return with an RTS, not with an RTE.
  512.     If you need to debug an XMOD module (i.e. if it doesn't work the first
  513. time), you can just set the first instruction at module+$04 to 'illegal'
  514. ($4AFC), activate a good debugger, and load the module from MultiPlayer.
  515. As soon as the player calls the module's init routine, it should kick into
  516. the debugger.
  517.  
  518.  
  519.  
  520.                         The AMOD format (obsolete)
  521.                         ~~~~~~~~~~~~~~~~~~~~~~~~~~
  522.  
  523.     The AMOD format is another special-purpose format MultiPlayer
  524. understands.  It is almost identical to the XMOD format, except in one
  525. respect:  AMOD modules always get loaded at a specific address.  For those
  526. few oddball music composer/player programs that like to write modules with
  527. lots of absolute addresses in them, this format may be the only good way to
  528. make the modules multitask.
  529.     The AMOD format is a simple extension to the XMOD format:
  530.  
  531. address+$00     'AMOD'
  532. address+$04     InitEntry
  533. address+$08     PlayEntry
  534. address+$0c     StopEntry
  535. address+$10     Load address
  536.  
  537.     When MultiPlayer encounters an AMOD module, it allocates memory for the
  538. module starting at the load address specified in the module.  The load
  539. address points to the location where the 'AMOD' identifier should go.  The
  540. module's code does not have to be PC-relative, since the load address is
  541. known.  Other than that, an AMOD module is loaded and executed the same way
  542. as an XMOD module.
  543.     If the required memory area is already occupied (even if it's just a
  544. few bytes somewhere in the required range), the module will not load.
  545. Therefore, the AMOD format should never be used except when absolutely
  546. necessary, since these modules may not be able to load even when there is
  547. enough memory available.  The memory does get allocated (the space is not
  548. just stomped on as with most European demos), so it will not cause the
  549. machine to crash; it just might not load sometimes when it should be able
  550. to.  I wish this module type wasn't necessary, but sometimes we just have
  551. to clean up somebody else's messes, don't we?
  552.  
  553.  
  554.  
  555.                               Version History
  556.                               ~~~~~~~~~~~~~~~
  557.  
  558. 1.01 (R2, 25-May-92)
  559.         Minor touchups, mainly in the Introduction.  Nothing really new.
  560.  
  561. 1.00 (R1, a long time ago)
  562.         The dawn of history.  (There were previous releases, but I wasn't
  563.             too organized with them...)
  564.  
  565.  
  566.  
  567.                               Contact Address
  568.                               ~~~~~~~~~~~~~~~
  569.  
  570.     I tend to move around a great deal, so mail sent directly to me
  571. sometimes has a hard time catching up.  If you want mail to reach me (it
  572. may take a while, but it WILL reach me), send it to this address:
  573.  
  574.         Bryan Ford
  575.         8749 Alta Hills Circle
  576.         Sandy, UT 84093
  577.  
  578.     I can be reached more quickly (for the time being anyway) on the phone
  579. or through one of the electronic mail addresses below:
  580.  
  581.         (801) 585-4619
  582.         bryan.ford@m.cc.utah.edu
  583.         baf0863@cc.utah.edu
  584.         baf0863@utahcca.bitnet
  585.  
  586.  
  587.